package com.earl.mbasystem.util;

import java.io.File;
import java.util.List;
import java.util.Map;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;

/**
 * Contributors: Mathias Bogaert
 */
public abstract class FileWatchDog extends Thread {
	/**
	 * log4j实例对象.
	 */
	private static Logger logger = LogManager.getLogger(FileWatchDog.class
			.getName());
	static final public long DEFAULT_DELAY = 60000;
	protected List<String> filename;
	protected long delay = DEFAULT_DELAY;

	Map<String,File> fileMap;
	
	Map<String,Long> lastModif;
	boolean warnedAlready = false;
	boolean interrupted = false;

	public FileWatchDog(List<String> filename) {
		super("FileWatchdog");
		this.filename = filename;
		for (String string : filename) {
			File tmpFile = new File(string);
			fileMap.put(string, tmpFile);
			if (tmpFile.exists()) {
				Long tmpModif = tmpFile.lastModified(); // this can also throw a
				lastModif.put(string, tmpModif);
				}
		}
		setDaemon(true);
		
		//SecurityException
		//checkAndConfigure();
	}

	/**
	 * Set the delay to observe between each check of the file changes.
	 */
	public void setDelay(long delay) {
		this.delay = delay;
	}

	abstract protected void doOnChange();

	protected Boolean checkAndConfigure(File file) {
		logger.debug("watching"+"[" + filename + "]");
		boolean fileExists;
		try {
			fileExists = file.exists();
		} catch (SecurityException e) {
			logger.warn("Was not allowed to read check file existance, file:["
					+ filename + "].");
			interrupted = true; // there is no point in continuing
			return false;
		}
		if (fileExists) {
			long l = file.lastModified(); // this can also throw a
											// SecurityException
			if (l > lastModif.get(file.getAbsolutePath())) { // however, if we reached this point this
				lastModif.put(file.getAbsolutePath(), l);// is very unlikely.
				doOnChange();
				warnedAlready = false;
				return true;
			}
		} else {
			if (!warnedAlready) {
				logger.debug("[" + filename + "] does not exist.");
				warnedAlready = true;
			}
		}
		return false;
	}

	public void run() {
		while (!interrupted) {
			try {
				Thread.sleep(delay);
			} catch (InterruptedException e) {
				// no interruption expected
				e.printStackTrace();
			}
			for (String file : filename) {
				Boolean change = checkAndConfigure(fileMap.get(file));
				if(change){
					break;
				}
			}
		}
	}
}
